﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Dominio;
using System.Data;
using LogicaNegocios.Exceptions;
using Persistencia;

namespace LogicaNegocios.Manager
{
    public class EventoManager
    {
        #region Singleton Code

        private static EventoManager _manager;

        private EventoManager() { }

        public static EventoManager GetManager()
        {
            if (_manager == null)
            {
                _manager = new EventoManager();
            }

            return _manager;
        }

        #endregion

        public void CrearEvento(Evento evento)
        {
            try
            {
                //No puede crearse un evento en el cual participen los mismos participantes en el mismo horario
                List<Evento> eventosExistentes = GetEventos();
                foreach (Evento eventoExistente in eventosExistentes)
                {
                    if (eventoExistente.FechaHora.Equals(evento.FechaHora))
                    {
                        foreach (Participante participante in evento.Participantes)
                        {
                            if (eventoExistente.Participantes.Contains(participante, new ParticipanteComparer()))
                            {
                                throw new EventoException(EventoException.PARTICIPANTE_YA_ASOCIADO_A_EVENTO);
                            }
                        }
                    }
                }

                //No puede crearse un evento en el cual los participantes no pertenezcan al deporte
                foreach (Participante participante in evento.Participantes)
                {                    
                    if (!participante.Deportes.Contains(evento.Deporte, new DeporteComparer()))
                    {
                        throw new EventoException(EventoException.DEPORTE_PARTICIPANTE_NO_ASOCIADO);
                    }
                }

                EventoPersistencia persistencia = new EventoPersistencia();
                persistencia.InsertarEvento(evento);
            }
            catch (DataException)
            {
                throw new DBException(DBException.ERROR_DB);
            }
        }

        public void EliminarEvento(Evento evento)
        {
            try
            {
                EventoPersistencia persistencia = new EventoPersistencia();
                persistencia.EliminarEvento(evento);
            }
            catch (DataException)
            {
                throw new DBException(DBException.ERROR_DB);
            }
        }

        public void ModificarEventoDatosPrincipales(Evento evento)
        {
            try
            {
                //No puede modificar un evento en el cual participen los mismos participantes en el mismo horario
                List<Evento> eventosExistentes = GetEventos();
                foreach (Evento eventoExistente in eventosExistentes)
                {
                    if (eventoExistente.Id != evento.Id)
                    {
                        if (eventoExistente.FechaHora.Equals(evento.FechaHora))
                        {
                            foreach (Participante participante in evento.Participantes)
                            {
                                if (eventoExistente.Participantes.Contains(participante, new ParticipanteComparer()))
                                {
                                    throw new EventoException(EventoException.PARTICIPANTE_YA_ASOCIADO_A_EVENTO);
                                }
                            }
                        }
                    }
                }

                EventoPersistencia persistencia = new EventoPersistencia();
                persistencia.ModificarEventoDatosPrincipales(evento);
            }
            catch (DataException)
            {
                throw new DBException(DBException.ERROR_DB);
            }
        }

        public void ModificarEventoParticipantes(Evento evento)
        {
            try
            {
                //No puede crearse un evento en el cual participen los mismos participantes en el mismo horario
                List<Evento> eventosExistentes = GetEventos();
                foreach (Evento eventoExistente in eventosExistentes)
                {
                    if (eventoExistente.Id != evento.Id)
                    {
                        if (eventoExistente.FechaHora.Equals(evento.FechaHora))
                        {
                            foreach (Participante participante in evento.Participantes)
                            {
                                if (eventoExistente.Participantes.Contains(participante, new ParticipanteComparer()))
                                {
                                    throw new EventoException(EventoException.PARTICIPANTE_YA_ASOCIADO_A_EVENTO);
                                }
                            }
                        }
                    }
                }

                //No puede crearse un evento en el cual los participantes no pertenezcan al deporte
                foreach (Participante participante in evento.Participantes)
                {
                    if (!participante.Deportes.Contains(evento.Deporte, new DeporteComparer()))
                    {
                        throw new EventoException(EventoException.DEPORTE_PARTICIPANTE_NO_ASOCIADO);
                    }
                }

                EventoPersistencia persistencia = new EventoPersistencia();
                persistencia.ModificarEventoParticipantes(evento);
            }
            catch (DataException)
            {
                throw new DBException(DBException.ERROR_DB);
            }
        }

        public void ModificarEventoResultados(Evento evento)
        {
            try
            {
                foreach (Resultado resultado in evento.Resultados)
                {
                    if (!evento.Participantes.Contains(resultado.Participante, new ParticipanteComparer()))
                    {
                        throw new EventoException(EventoException.RESULTADO_PARTICIPANTE_NO_ASOCIADO);
                    }
                }

                EventoPersistencia persistencia = new EventoPersistencia();
                persistencia.ModificarEventoResultados(evento);
            }
            catch (DataException)
            {
                throw new DBException(DBException.ERROR_DB);
            }
        }

        public List<Evento> GetEventos()
        {
            List<Evento> eventos = null;

            try
            {
                EventoPersistencia persistencia = new EventoPersistencia();
                eventos = persistencia.GetEventos();
            }
            catch (DataException)
            {
                throw new DBException(DBException.ERROR_DB);
            }

            return eventos;
        }

        public List<Evento> GetEventosSimple()
        {
            List<Evento> eventos = null;

            try
            {
                EventoPersistencia persistencia = new EventoPersistencia();
                eventos = persistencia.GetEventosSimple();
            }
            catch (DataException)
            {
                throw new DBException(DBException.ERROR_DB);
            }

            return eventos;
        }

        public System.Data.DataSet GetResultadosMedallasPorPais()
        {
            try
            {
                EventoPersistencia persistencia = new EventoPersistencia();
                return persistencia.GetResultadosMedallasPorPais();
            }
            catch (DataException)
            {
                throw new DBException(DBException.ERROR_DB);
            }
        }

        public System.Data.DataSet GetEventosPorDeporte()
        {
            try
            {
                EventoPersistencia persistencia = new EventoPersistencia();
                return persistencia.GetEventosPorDeporte();
            }
            catch (DataException)
            {
                throw new DBException(DBException.ERROR_DB);
            }
        }

        public Evento GetEvento(int eventoId)
        {
            try
            {
                EventoPersistencia persistencia = new EventoPersistencia();
                return persistencia.GetEvento(eventoId);
            }
            catch (DataException)
            {
                throw new DBException(DBException.ERROR_DB);
            }
        }

        public Resultado GetResultado(int participanteId, List<Resultado> resultados)
        {
            Resultado resultado = null;

            foreach (Resultado resultadoAux in resultados)
            {
                if (resultadoAux != null && resultadoAux.Participante.Id.Equals(participanteId))
                {
                    resultado = resultadoAux;
                    break;
                }
            }

            return resultado;
        }
       
    }
}
